package com.nuc.bigdata.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.DefaultThumbImageConfig;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.nuc.bigdata.orm.entity.Picture;
import com.nuc.bigdata.orm.mapper.PictureMapper;
import com.nuc.bigdata.service.PictureService;
import com.nuc.bigdata.util.FileUtil;
import com.nuc.bigdata.util.RegexUtil;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotEmpty;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author JackLuo
 * @date 2019/11/14
 */
@Service
public class PictureServiceImpl implements PictureService {

    private final FastFileStorageClient fileStorageClient;

    private final PictureMapper mapper;

    private final DefaultThumbImageConfig imageConfig;

    private final FdfsWebServer fdfsWebServer;

    private Picture picture = new Picture();

    private String pictureType;

    @Autowired
    PictureServiceImpl(PictureMapper mapper,
                       FastFileStorageClient fileStorageClient,
                       DefaultThumbImageConfig imageConfig,
                       FdfsWebServer fdfsWebServer) {
        this.mapper = mapper;
        this.fileStorageClient = fileStorageClient;
        this.imageConfig = imageConfig;
        this.fdfsWebServer = fdfsWebServer;
    }


    /**
     * @param file MultipartFile 网页文件选择
     * @param userId 用户id
     * @return
     */
    @Override
    @Transactional(rollbackForClassName = "Exception")
    public Picture uploadPicture(MultipartFile file,String userId) {
        String pictureId = getPictureId();
        String pictureOriginalName = getPictureOriginalName(file);
        picture.setPictureId(pictureId);
        picture.setPictureOriginalName(pictureOriginalName);
        setPicturePathAndPictureName(file);
        setPictureSizeAndUom(file);
        picture.setCreatedBy(userId);
        mapper.insert(picture);
        return picture;
    }

    @Override
    public Picture getPicture(String pictureId) {
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("picture_id",pictureId );
        Picture picture = mapper.selectOne(queryWrapper);
        return picture;
    }

    @Override
    public String getPictureUrl(Picture picture) {
        String webServerUrl = fdfsWebServer.getWebServerUrl();
        String pictureName = picture.getPictureName();
        String picturePath = picture.getPicturePath();
        String pictureType = picture.getPictureType();
        String url = webServerUrl + "/"+picturePath+pictureName+"."+pictureType;
        return url;
    }

    @Override
    public String getThumbnailUrl(Picture picture) {
        String webServerUrl = fdfsWebServer.getWebServerUrl();
        String thumbnail = picture.getThumbnail();
        String picturePath = picture.getPicturePath();
        String pictureType = picture.getPictureType();
        String thumbnailUrl = webServerUrl + "/"+picturePath+thumbnail+"."+pictureType;
        return thumbnailUrl;
    }

    /**
     * 一次性上传多个文件
     *
     * @param files  包含MultipartFile的ArrayList
     * @param userId 用户唯一标识
     * @return 图片信息的ArrayList
     */
    @Override
    @Transactional(rollbackForClassName = "Exception")
    public ArrayList<Picture> uploadManyPicture(ArrayList<MultipartFile> files, String userId) {
        ArrayList<Picture> pictureArrayList = new ArrayList<>();
        for (MultipartFile file:files){
            Picture newPicture= uploadPicture(file, userId);
            pictureArrayList.add(newPicture);
            picture =new Picture();
        }
        return pictureArrayList;
    }

    String getPictureOriginalName(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        return originalFilename.substring(0, originalFilename.lastIndexOf('.'));
    }

    String getPictureType(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();

        if (originalFilename.matches(RegexUtil.FILE_TYPE)) {
            return originalFilename.substring(originalFilename.lastIndexOf('.') + 1);
        } else {
            return null;
        }
    }

    void setPictureType(MultipartFile file) {
        pictureType = getPictureType(file);
        picture.setPictureType(pictureType);
    }

    String getPictureId() {
        return IdUtil.fastSimpleUUID();
    }


    /**
     * setPictureSize
     * setPictureUom
     *
     * @param file
     */
    void setPictureSizeAndUom(MultipartFile file) {
        long size = file.getSize();
        HashMap<String, Object> fileSizeAndUom = FileUtil.getFileSizeAndUom(size);
        BigDecimal pictureSize = (BigDecimal) fileSizeAndUom.get(FileUtil.SIZE);
        String uom = (String) fileSizeAndUom.get(FileUtil.UOM);
        picture.setPictureSize(pictureSize);
        picture.setPictureSizeUom(uom);
    }

    /**
     * 传输文件
     * setPictureType
     *
     * @param file
     * @return
     */
    StorePath transferPicture(MultipartFile file) {
        setPictureType(file);
        try {
            return fileStorageClient.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(), pictureType, null);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * setPicturePath
     * setPictureName
     * setThumbnail
     *
     * @param file
     */
    void setPicturePathAndPictureName(MultipartFile file) {
        String prefixName = imageConfig.getPrefixName();

        StorePath storePath = transferPicture(file);
        String fullPath = storePath.getFullPath();
        int lastIndexOfName = fullPath.lastIndexOf('/');
        String picturePath = fullPath.substring(0, lastIndexOfName + 1);
        int lastIndexOfType = fullPath.lastIndexOf('.');
        String pictureName = fullPath.substring(lastIndexOfName + 1, lastIndexOfType);

        picture.setThumbnail(pictureName + prefixName);
        picture.setPicturePath(picturePath);
        picture.setPictureName(pictureName);
    }


}
